home *** CD-ROM | disk | FTP | other *** search
- /*
- unmount.c --- unmount filesystems.
-
- (c) Copyright 1995-98 SHW Wabnitz
- Written by Bernhard Fastenrath (fasten@shw.com)
-
- This file may be distributed under the terms
- of the GNU General Public License.
- */
-
- #include "shutdown_cmd.h"
- #include <stdio.h>
-
- typedef struct {
- struct Message sp_Msg;
- struct DosPacket sp_Pkt;
- struct Node *sp_Dev;
- } MyStandardPacket;
-
- /// FreeList()
- static void
- FreeList (List *list)
- {
- Node *node, *next;
-
- for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
- {
- if (node -> ln_Name)
- FreeMem (node -> ln_Name, node -> ln_Pri);
- FreeMem (node, sizeof (Node));
- }
- }
- ///
-
- /// FreeStdPktList()
- static void
- FreeStdPktList (List *list)
- {
- Node *node, *next;
-
- for (next = node = list -> lh_Head; next = node -> ln_Succ; node = next)
- FreeMem (node, sizeof (MyStandardPacket));
- }
- ///
-
- /// SendStandardPacket()
- static int
- SendStandardPacket (MsgPort *mp, MyStandardPacket *sp, char *handler, ULONG action, ULONG arg1)
- {
- DevProc *dp = NULL;
-
- dp = GetDeviceProc (handler, dp);
- if (dp)
- {
- sp -> sp_Pkt.dp_Type = action;
- sp -> sp_Pkt.dp_Arg1 = arg1;
- SendPkt (&sp -> sp_Pkt, dp -> dvp_Port, mp);
- FreeDeviceProc (dp);
- return 1;
- }
- return 0;
- }
- ///
-
- /// AllocateStandardPackets ()
- static int
- AllocateStandardPackets (List *pktlist, int count)
- {
- MyStandardPacket *sp;
- int t;
-
- NewList (pktlist);
-
- for (t=0; t<count; t++)
- {
- if (!(sp = AllocMem (sizeof (MyStandardPacket), MEMF_PUBLIC | MEMF_CLEAR)))
- break;
- sp -> sp_Msg.mn_Length = sizeof (MyStandardPacket);
- sp -> sp_Msg.mn_Node.ln_Name = (char *) &sp -> sp_Pkt;
- sp -> sp_Pkt.dp_Link = &sp -> sp_Msg;
- AddTail (pktlist, &sp -> sp_Msg.mn_Node);
- }
- return t;
- }
- ///
-
- /// SendToAll()
- static int
- SendToAll (MsgPort *mp, ULONG action, ULONG arg1)
- {
- int len, count = 0, icount = 0, out_of_mem = 0;
- List devlist, pktlist;
- MyStandardPacket *sp;
- Node *node;
- DosList *dl;
- char *name;
-
- NewList (&devlist);
- NewList (&pktlist);
-
- dl = LockDosList ( LDF_DEVICES | LDF_READ );
-
- while (dl = NextDosEntry (dl, LDF_DEVICES))
- {
- if (node = (Node *) AllocMem (sizeof (Node), MEMF_CLEAR))
- {
- name = BADDR (dl -> dol_Name);
- len = (int) name[0];
-
- if (node -> ln_Name = AllocMem (len + 2, 0))
- {
- CopyMem (name+1, node -> ln_Name, len);
- node -> ln_Name[len] = ':';
- node -> ln_Name[len+1] = '\0';
- node -> ln_Pri = len + 2;
- AddTail (&devlist, node);
- count ++;
- }
- else
- {
- out_of_mem = 1;
- FreeMem (node, sizeof (Node));
- break;
- }
- }
- }
-
- UnLockDosList ( LDF_DEVICES | LDF_READ );
-
- if ((icount = AllocateStandardPackets (&pktlist, count)) == 0)
- out_of_mem = 1;
- count = icount;
-
- if (out_of_mem)
- {
- FreeStdPktList (&pktlist);
- FreeList (&devlist);
- return 0;
- }
-
- node = devlist.lh_Head;
- for (;;)
- {
- while (node -> ln_Succ)
- {
- if (sp = (MyStandardPacket *) RemHead (&pktlist))
- {
- sp -> sp_Dev = node;
- SendStandardPacket (mp, sp, node -> ln_Name, ACTION_IS_FILESYSTEM, 0);
- icount --;
- node = node -> ln_Succ;
- }
- }
- WaitPort (mp);
-
- while (sp = (MyStandardPacket *) GetMsg (mp))
- {
- icount ++;
-
- if (sp -> sp_Pkt.dp_Type == ACTION_IS_FILESYSTEM &&
- sp -> sp_Pkt.dp_Res1 == DOSTRUE)
- {
- SendStandardPacket (mp, sp, sp -> sp_Dev -> ln_Name, action, arg1);
- icount --;
- }
- else
- {
- AddTail (&pktlist, &sp -> sp_Msg.mn_Node);
- }
- }
- if (!node -> ln_Succ && icount == count)
- break;
- }
- FreeStdPktList (&pktlist);
- FreeList (&devlist);
- return 1;
- }
- ///
-
- /// FsAction()
- static int
- FsAction (MsgPort *mp, ULONG action, ULONG arg)
- {
- return !SendToAll (mp, action, arg);
- }
- ///
-
- /*** public functions ***/
-
- /// Unmount()
- int
- Unmount (char *filesystem, int mode)
- {
- MsgPort *mp;
- int status;
-
- if (!(mp = CreatePort (NULL, 0)))
- return 0;
-
- switch (mode)
- {
- case UMNT_INHIBIT:
- status = FsAction (mp, ACTION_INHIBIT, DOSTRUE);
- break;
- case UMNT_READONLY:
- status = FsAction (mp, ACTION_FLUSH, DOSTRUE);
- status |= FsAction (mp, ACTION_WRITE_PROTECT, DOSTRUE);
- break;
- case UMNT_REMOUNT:
- /* status = FsAction (mp, ACTION_WRITE_PROTECT, DOSFALSE); */
- status = FsAction (mp, ACTION_INHIBIT, DOSTRUE);
- status |= FsAction (mp, ACTION_INHIBIT, DOSFALSE);
- break;
- }
- DeletePort (mp);
- return !status;
- }
- ///
-